home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programmierung
/
Power-Programmierung (Tewi)(1994).iso
/
magazine
/
drdobbs
/
1991
/
12
/
dflat.121
< prev
next >
Wrap
Text File
|
1991-11-11
|
27KB
|
861 lines
_C PROGRAMMING COLUMN_
by Al Stevens
[LISTING ONE]
/* ------------- textbox.c ------------ */
#include "dflat.h"
#ifdef INCLUDE_SCROLLBARS
static void ComputeWindowTop(WINDOW);
static void ComputeWindowLeft(WINDOW);
static int ComputeVScrollBox(WINDOW);
static int ComputeHScrollBox(WINDOW);
static void MoveScrollBox(WINDOW, int);
#endif
static char *GetTextLine(WINDOW, int);
#ifdef INCLUDE_SCROLLBARS
int VSliding;
int HSliding;
#endif
/* ------------ ADDTEXT Message -------------- */
static void AddTextMsg(WINDOW wnd, PARAM p1)
{
/* --- append text to the textbox's buffer --- */
unsigned adln = strlen((char *)p1);
if (adln > (unsigned)0xfff0)
return;
if (wnd->text != NULL) {
/* ---- appending to existing text ---- */
unsigned txln = strlen(wnd->text);
if ((long)txln+adln > (unsigned) 0xfff0)
return;
if (txln+adln > wnd->textlen) {
wnd->text = realloc(wnd->text, txln+adln+3);
wnd->textlen = txln+adln+1;
}
}
else {
/* ------ 1st text appended ------ */
wnd->text = calloc(1, adln+3);
wnd->textlen = adln+1;
}
if (wnd->text != NULL) {
/* ---- append the text ---- */
strcat(wnd->text, (char*) p1);
strcat(wnd->text, "\n");
BuildTextPointers(wnd);
}
}
/* ------------ SETTEXT Message -------------- */
static void SetTextMsg(WINDOW wnd, PARAM p1)
{
/* -- assign new text value to textbox buffer -- */
char *cp;
unsigned int len;
cp = (void *) p1;
len = strlen(cp)+1;
if (wnd->text == NULL || wnd->textlen < len) {
wnd->textlen = len;
if ((wnd->text=realloc(wnd->text, len+1)) == NULL)
return;
wnd->text[len] = '\0';
}
strcpy(wnd->text, cp);
BuildTextPointers(wnd);
}
/* ------------ CLEARTEXT Message -------------- */
static void ClearTextMsg(WINDOW wnd)
{
/* ----- clear text from textbox ----- */
if (wnd->text != NULL)
free(wnd->text);
wnd->text = NULL;
wnd->textlen = 0;
wnd->wlines = 0;
wnd->textwidth = 0;
wnd->wtop = wnd->wleft = 0;
ClearBlock(wnd);
ClearTextPointers(wnd);
}
/* ------------ KEYBOARD Message -------------- */
static int KeyboardMsg(WINDOW wnd, PARAM p1)
{
switch ((int) p1) {
case UP:
return SendMessage(wnd,SCROLL,FALSE,0);
case DN:
return SendMessage(wnd,SCROLL,TRUE,0);
case FWD:
return SendMessage(wnd,HORIZSCROLL,TRUE,0);
case BS:
return SendMessage(wnd,HORIZSCROLL,FALSE,0);
case PGUP:
return SendMessage(wnd,SCROLLPAGE,FALSE,0);
case PGDN:
return SendMessage(wnd,SCROLLPAGE,TRUE,0);
case CTRL_PGUP:
return SendMessage(wnd,HORIZPAGE,FALSE,0);
case CTRL_PGDN:
return SendMessage(wnd,HORIZPAGE,TRUE,0);
case HOME:
return SendMessage(wnd,SCROLLDOC,TRUE,0);
case END:
return SendMessage(wnd,SCROLLDOC,FALSE,0);
default:
break;
}
return FALSE;
}
#ifdef INCLUDE_SCROLLBARS
/* ------------ LEFT_BUTTON Message -------------- */
static int LeftButtonMsg(WINDOW wnd, PARAM p1, PARAM p2)
{
int mx = (int) p1 - GetLeft(wnd);
int my = (int) p2 - GetTop(wnd);
if (TestAttribute(wnd, VSCROLLBAR) &&
mx == WindowWidth(wnd)-1) {
/* -------- in the right border ------- */
if (my == 0 || my == ClientHeight(wnd)+1)
/* --- above or below the scroll bar --- */
return FALSE;
if (my == 1)
/* -------- top scroll button --------- */
return SendMessage(wnd, SCROLL, FALSE, 0);
if (my == ClientHeight(wnd))
/* -------- bottom scroll button --------- */
return SendMessage(wnd, SCROLL, TRUE, 0);
/* ---------- in the scroll bar ----------- */
if (!VSliding && my-1 == wnd->VScrollBox) {
RECT rc;
VSliding = TRUE;
rc.lf = rc.rt = GetRight(wnd);
rc.tp = GetTop(wnd)+2;
rc.bt = GetBottom(wnd)-2;
return SendMessage(NULL, MOUSE_TRAVEL,
(PARAM) &rc, 0);
}
if (my-1 < wnd->VScrollBox)
return SendMessage(wnd,SCROLLPAGE,FALSE,0);
if (my-1 > wnd->VScrollBox)
return SendMessage(wnd,SCROLLPAGE,TRUE,0);
}
if (TestAttribute(wnd, HSCROLLBAR) &&
my == WindowHeight(wnd)-1) {
/* -------- in the bottom border ------- */
if (mx == 0 || my == ClientWidth(wnd)+1)
/* ------ outside the scroll bar ---- */
return FALSE;
if (mx == 1)
return SendMessage(wnd, HORIZSCROLL,FALSE,0);
if (mx == WindowWidth(wnd)-2)
return SendMessage(wnd, HORIZSCROLL,TRUE,0);
if (!HSliding && mx-1 == wnd->HScrollBox) {
/* --- hit the scroll box --- */
RECT rc;
rc.lf = GetLeft(wnd)+2;
rc.rt = GetRight(wnd)-2;
rc.tp = rc.bt = GetBottom(wnd);
/* - keep the mouse in the scroll bar - */
SendMessage(NULL,MOUSE_TRAVEL,(PARAM)&rc,0);
HSliding = TRUE;
return TRUE;
}
if (mx-1 < wnd->HScrollBox)
return SendMessage(wnd,HORIZPAGE,FALSE,0);
if (mx-1 > wnd->HScrollBox)
return SendMessage(wnd,HORIZPAGE,TRUE,0);
}
return FALSE;
}
/* ------------ MOUSE_MOVED Message -------------- */
static int MouseMovedMsg(WINDOW wnd, PARAM p1, PARAM p2)
{
int mx = (int) p1 - GetLeft(wnd);
int my = (int) p2 - GetTop(wnd);
if (VSliding) {
/* ---- dragging the vertical scroll box --- */
if (my-1 != wnd->VScrollBox) {
foreground = FrameForeground(wnd);
background = FrameBackground(wnd);
PutWindowChar(wnd, WindowWidth(wnd)-1,
wnd->VScrollBox+1,SCROLLBARCHAR);
wnd->VScrollBox = my-1;
PutWindowChar(wnd, WindowWidth(wnd)-1,
my, SCROLLBOXCHAR);
}
return TRUE;
}
if (HSliding) {
/* --- dragging the horizontal scroll box --- */
if (mx-1 != wnd->HScrollBox) {
foreground = FrameForeground(wnd);
background = FrameBackground(wnd);
PutWindowChar(wnd, wnd->HScrollBox+1,
WindowHeight(wnd)-1, SCROLLBARCHAR);
wnd->HScrollBox = mx-1;
PutWindowChar(wnd, mx, WindowHeight(wnd)-1,
SCROLLBOXCHAR);
}
return TRUE;
}
return FALSE;
}
/* ------------ BUTTON_RELEASED Message -------------- */
static void ButtonReleasedMsg(WINDOW wnd)
{
if (HSliding || VSliding) {
RECT rc;
rc.lf = rc.tp = 0;
rc.rt = SCREENWIDTH-1;
rc.bt = SCREENHEIGHT-1;
/* release the mouse ouside the scroll bar */
SendMessage(NULL, MOUSE_TRAVEL, (PARAM) &rc, 0);
VSliding ? ComputeWindowTop(wnd) :
ComputeWindowLeft(wnd);
SendMessage(wnd, PAINT, 0, 0);
SendMessage(wnd, KEYBOARD_CURSOR, 0, 0);
VSliding = HSliding = FALSE;
}
}
#endif
/* ------------ SCROLL Message -------------- */
static int ScrollMsg(WINDOW wnd, PARAM p1)
{
/* ---- vertical scroll one line ---- */
if (p1) {
/* ----- scroll one line up ----- */
if (wnd->wtop+ClientHeight(wnd) >= wnd->wlines)
return FALSE;
wnd->wtop++;
}
else {
/* ----- scroll one line down ----- */
if (wnd->wtop == 0)
return FALSE;
--wnd->wtop;
}
if (isVisible(wnd)) {
RECT rc;
rc = ClipRectangle(wnd, ClientRect(wnd));
if (ValidRect(rc)) {
/* ---- scroll the window ----- */
scroll_window(wnd, rc, (int)p1);
if (!(int)p1)
/* -- write top line (down) -- */
WriteTextLine(wnd,NULL,wnd->wtop,FALSE);
else {
/* -- write bottom line (up) -- */
int y=RectBottom(rc)-GetClientTop(wnd);
WriteTextLine(wnd, NULL,
wnd->wtop+y, FALSE);
}
}
#ifdef INCLUDE_SCROLLBARS
/* ---- reset the scroll box ---- */
if (TestAttribute(wnd, VSCROLLBAR)) {
int vscrollbox = ComputeVScrollBox(wnd);
if (vscrollbox != wnd->VScrollBox)
MoveScrollBox(wnd, vscrollbox);
}
#endif
return TRUE;
}
return FALSE;
}
/* ------------ HORIZSCROLL Message -------------- */
static void HorizScrollMsg(WINDOW wnd, PARAM p1)
{
/* --- horizontal scroll one column --- */
if (p1) {
/* --- scroll left --- */
if (wnd->wleft + ClientWidth(wnd)-1 <
wnd->textwidth)
wnd->wleft++;
}
else
/* --- scroll right --- */
if (wnd->wleft > 0)
--wnd->wleft;
SendMessage(wnd, PAINT, 0, 0);
}
/* ------------ SCROLLPAGE Message -------------- */
static void ScrollPageMsg(WINDOW wnd, PARAM p1)
{
/* --- vertical scroll one page --- */
if ((int) p1 == FALSE) {
/* ---- page up ---- */
if (wnd->wtop) {
wnd->wtop -= ClientHeight(wnd);
if (wnd->wtop < 0)
wnd->wtop = 0;
}
}
else {
/* ---- page down ---- */
if (wnd->wtop+ClientHeight(wnd) < wnd->wlines) {
wnd->wtop += ClientHeight(wnd);
if (wnd->wtop>wnd->wlines-ClientHeight(wnd))
wnd->wtop=wnd->wlines-ClientHeight(wnd);
}
}
SendMessage(wnd, PAINT, 0, 0);
}
/* ------------ HORIZSCROLLPAGE Message -------------- */
static void HorizScrollPageMsg(WINDOW wnd, PARAM p1)
{
/* --- horizontal scroll one page --- */
if ((int) p1 == FALSE) {
/* ---- page left ----- */
wnd->wleft -= ClientWidth(wnd);
if (wnd->wleft < 0)
wnd->wleft = 0;
}
else {
/* ---- page right ----- */
wnd->wleft += ClientWidth(wnd);
if (wnd->wleft>wnd->textwidth-ClientWidth(wnd))
wnd->wleft=wnd->textwidth-ClientWidth(wnd);
}
SendMessage(wnd, PAINT, 0, 0);
}
/* ------------ SCROLLDOC Message -------------- */
static void ScrollDocMsg(WINDOW wnd, PARAM p1)
{
/* --- scroll to beginning or end of document --- */
if ((int) p1)
wnd->wtop = wnd->wleft = 0;
else if (wnd->wtop+ClientHeight(wnd) < wnd->wlines){
wnd->wtop = wnd->wlines-ClientHeight(wnd);
wnd->wleft = 0;
}
SendMessage(wnd, PAINT, 0, 0);
}
/* ------------ PAINT Message -------------- */
static int PaintMsg(WINDOW wnd, PARAM p1)
{
/* ------ paint the client area ----- */
RECT rc, rcc;
int y;
char blankline[201];
/* ----- build the rectangle to paint ----- */
if ((RECT *)p1 == NULL)
rc=RelativeWindowRect(wnd, WindowRect(wnd));
else
rc= *(RECT *)p1;
if (TestAttribute(wnd, HASBORDER) &&
RectRight(rc) >= WindowWidth(wnd)-1) {
if (RectLeft(rc) >= WindowWidth(wnd)-1)
return FALSE;
RectRight(rc) = WindowWidth(wnd)-2;
}
rcc = AdjustRectangle(wnd, rc);
/* ----- blank line for padding ----- */
memset(blankline, ' ', SCREENWIDTH);
blankline[RectRight(rcc)+1] = '\0';
/* ------- each line within rectangle ------ */
for (y = RectTop(rc); y <= RectBottom(rc); y++){
int yy;
/* ---- test outside of Client area ---- */
if (TestAttribute(wnd,
HASBORDER | HASTITLEBAR)) {
if (y < TopBorderAdj(wnd))
continue;
if (y > WindowHeight(wnd)-2)
continue;
}
yy = y-TopBorderAdj(wnd);
if (yy < wnd->wlines-wnd->wtop)
/* ---- paint a text line ---- */
WriteTextLine(wnd, &rc,
yy+wnd->wtop, FALSE);
else {
/* ---- paint a blank line ---- */
SetStandardColor(wnd);
writeline(wnd, blankline+RectLeft(rcc),
RectLeft(rcc)+1, y, FALSE);
}
}
#ifdef INCLUDE_SCROLLBARS
/* ------- position the scroll box ------- */
if (TestAttribute(wnd, VSCROLLBAR|HSCROLLBAR)) {
int hscrollbox = ComputeHScrollBox(wnd);
int vscrollbox = ComputeVScrollBox(wnd);
if (hscrollbox != wnd->HScrollBox ||
vscrollbox != wnd->VScrollBox) {
wnd->HScrollBox = hscrollbox;
wnd->VScrollBox = vscrollbox;
SendMessage(wnd, BORDER, p1, 0);
}
}
#endif
return TRUE;
}
/* ------------ CLOSE_WINDOW Message -------------- */
static void CloseWindowMsg(WINDOW wnd)
{
SendMessage(wnd, CLEARTEXT, 0, 0);
if (wnd->TextPointers != NULL) {
free(wnd->TextPointers);
wnd->TextPointers = NULL;
}
}
/* ----------- TEXTBOX Message-processing Module ----------- */
int TextBoxProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2)
{
switch (msg) {
case CREATE_WINDOW:
wnd->HScrollBox = wnd->VScrollBox = 1;
ClearTextPointers(wnd);
break;
case ADDTEXT:
AddTextMsg(wnd, p1);
break;
case SETTEXT:
SetTextMsg(wnd, p1);
break;
case CLEARTEXT:
ClearTextMsg(wnd);
break;
case KEYBOARD:
#ifdef INCLUDE_SYSTEM_MENUS
if (WindowMoving || WindowSizing)
return FALSE;
#endif
if (KeyboardMsg(wnd, p1))
return TRUE;
break;
case LEFT_BUTTON:
#ifdef INCLUDE_SYSTEM_MENUS
if (WindowSizing || WindowMoving)
return FALSE;
#endif
#ifdef INCLUDE_SCROLLBARS
if (LeftButtonMsg(wnd, p1, p2))
return TRUE;
break;
case MOUSE_MOVED:
if (MouseMovedMsg(wnd, p1, p2))
return TRUE;
break;
case BUTTON_RELEASED:
ButtonReleasedMsg(wnd);
#endif
break;
case SCROLL:
ScrollMsg(wnd, p1);
return TRUE;
case HORIZSCROLL:
HorizScrollMsg(wnd, p1);
return TRUE;
case SCROLLPAGE:
ScrollPageMsg(wnd, p1);
return TRUE;
case HORIZPAGE:
HorizScrollPageMsg(wnd, p1);
return TRUE;
case SCROLLDOC:
ScrollDocMsg(wnd, p1);
return TRUE;
case PAINT:
if (isVisible(wnd) && wnd->wlines) {
PaintMsg(wnd, p1);
return FALSE;
}
break;
case CLOSE_WINDOW:
CloseWindowMsg(wnd);
break;
default:
break;
}
return BaseWndProc(TEXTBOX, wnd, msg, p1, p2);
}
#ifdef INCLUDE_SCROLLBARS
/* ------ compute the vertical scroll box position from
the text pointers --------- */
static int ComputeVScrollBox(WINDOW wnd)
{
int pagelen = wnd->wlines - ClientHeight(wnd);
int barlen = ClientHeight(wnd)-2;
int lines_tick;
int vscrollbox;
if (pagelen < 1 || barlen < 1)
vscrollbox = 1;
else {
if (pagelen > barlen)
lines_tick = pagelen / barlen;
else
lines_tick = barlen / pagelen;
vscrollbox = 1 + (wnd->wtop / lines_tick);
if (vscrollbox > ClientHeight(wnd)-2 ||
wnd->wtop + ClientHeight(wnd) >= wnd->wlines)
vscrollbox = ClientHeight(wnd)-2;
}
return vscrollbox;
}
/* ---- compute top text line from scroll box position ---- */
static void ComputeWindowTop(WINDOW wnd)
{
int pagelen = wnd->wlines - ClientHeight(wnd);
if (wnd->VScrollBox == 0)
wnd->wtop = 0;
else if (wnd->VScrollBox == ClientHeight(wnd)-2)
wnd->wtop = pagelen;
else {
int barlen = ClientHeight(wnd)-2;
int lines_tick;
if (pagelen > barlen)
lines_tick = pagelen / barlen;
else
lines_tick = barlen / pagelen;
wnd->wtop = (wnd->VScrollBox-1) * lines_tick;
if (wnd->wtop + ClientHeight(wnd) > wnd->wlines)
wnd->wtop = pagelen;
}
if (wnd->wtop < 0)
wnd->wtop = 0;
}
/* ------ compute the horizontal scroll box position from
the text pointers --------- */
static int ComputeHScrollBox(WINDOW wnd)
{
int pagewidth = wnd->textwidth - ClientWidth(wnd);
int barlen = ClientWidth(wnd)-2;
int chars_tick;
int hscrollbox;
if (pagewidth < 1 || barlen < 1)
hscrollbox = 1;
else {
if (pagewidth > barlen)
chars_tick = pagewidth / barlen;
else
chars_tick = barlen / pagewidth;
hscrollbox = 1 + (wnd->wleft / chars_tick);
if (hscrollbox > ClientWidth(wnd)-2 ||
wnd->wleft + ClientWidth(wnd) >= wnd->textwidth)
hscrollbox = ClientWidth(wnd)-2;
}
return hscrollbox;
}
/* ---- compute left column from scroll box position ---- */
static void ComputeWindowLeft(WINDOW wnd)
{
int pagewidth = wnd->textwidth - ClientWidth(wnd);
if (wnd->HScrollBox == 0)
wnd->wleft = 0;
else if (wnd->HScrollBox == ClientWidth(wnd)-2)
wnd->wleft = pagewidth;
else {
int barlen = ClientWidth(wnd)-2;
int chars_tick;
if (pagewidth > barlen)
chars_tick = pagewidth / barlen;
else
chars_tick = barlen / pagewidth;
wnd->wleft = (wnd->HScrollBox-1) * chars_tick;
if (wnd->wleft + ClientWidth(wnd) > wnd->textwidth)
wnd->wleft = pagewidth;
}
if (wnd->wleft < 0)
wnd->wleft = 0;
}
#endif
/* ----- get the text to a specified line ----- */
static char *GetTextLine(WINDOW wnd, int selection)
{
char *line;
int len = 0;
char *cp, *cp1;
cp = cp1 = TextLine(wnd, selection);
while (*cp && *cp != '\n') {
len++;
cp++;
}
line = malloc(len+6);
if (line != NULL) {
memmove(line, cp1, len);
line[len] = '\0';
}
return line;
}
/* ------- write a line of text to a textbox window ------- */
void WriteTextLine(WINDOW wnd, RECT *rcc, int y, int reverse)
{
int len = 0;
int dif = 0;
unsigned char *line;
RECT rc;
unsigned char *lp, *svlp;
int lnlen;
int i;
int trunc = FALSE;
/* ------ make sure y is inside the window ----- */
if (y < wnd->wtop || y >= wnd->wtop+ClientHeight(wnd))
return;
/* ---- build the retangle within which can write ---- */
if (rcc == NULL) {
rc = RelativeWindowRect(wnd, WindowRect(wnd));
if (TestAttribute(wnd, HASBORDER) &&
RectRight(rc) >= WindowWidth(wnd)-1)
RectRight(rc) = WindowWidth(wnd)-2;
}
else
rc = *rcc;
/* ----- make sure rectangle is within window ------ */
if (RectLeft(rc) >= WindowWidth(wnd)-1)
return;
if (RectRight(rc) == 0)
return;
rc = AdjustRectangle(wnd, rc);
if (y-wnd->wtop<RectTop(rc) || y-wnd->wtop>RectBottom(rc))
return;
/* --- get the text and length of the text line --- */
lp = svlp = GetTextLine(wnd, y);
if (svlp == NULL)
return;
lnlen = LineLength(lp);
/* -------- insert block color change controls ------- */
if (BlockMarked(wnd)) {
int bbl = wnd->BlkBegLine;
int bel = wnd->BlkEndLine;
int bbc = wnd->BlkBegCol;
int bec = wnd->BlkEndCol;
int by = y;
/* ----- put lowest marker first ----- */
if (bbl > bel) {
swap(bbl, bel);
swap(bbc, bec);
}
if (bbl == bel && bbc > bec)
swap(bbc, bec);
if (by >= bbl && by <= bel) {
/* ------ the block includes this line ----- */
int blkbeg = 0;
int blkend = lnlen;
if (!(by > bbl && by < bel)) {
/* --- the entire line is not in the block -- */
if (by == bbl)
/* ---- the block begins on this line --- */
blkbeg = bbc;
if (by == bel)
/* ---- the block ends on this line ---- */
blkend = bec;
}
/* ----- insert the reset color token ----- */
memmove(lp+blkend+1,lp+blkend,strlen(lp+blkend)+1);
lp[blkend] = RESETCOLOR;
/* ----- insert the change color token ----- */
memmove(lp+blkbeg+3,lp+blkbeg,strlen(lp+blkbeg)+1);
lp[blkbeg] = CHANGECOLOR;
/* ----- insert the color tokens ----- */
SetReverseColor(wnd);
lp[blkbeg+1] = foreground | 0x80;
lp[blkbeg+2] = background | 0x80;
lnlen += 4;
}
}
/* - make sure left margin doesn't overlap color change - */
for (i = 0; i < wnd->wleft+3; i++) {
if (*(lp+i) == '\0')
break;
if (*(unsigned char *)(lp + i) == RESETCOLOR)
break;
}
if (*(lp+i) && i < wnd->wleft+3) {
if (wnd->wleft+4 > lnlen)
trunc = TRUE;
else
lp += 4;
}
else {
/* --- it does, shift the color change over --- */
for (i = 0; i < wnd->wleft; i++) {
if (*(lp+i) == '\0')
break;
if (*(unsigned char *)(lp + i) == CHANGECOLOR) {
*(lp+wnd->wleft+2) = *(lp+i+2);
*(lp+wnd->wleft+1) = *(lp+i+1);
*(lp+wnd->wleft) = *(lp+i);
break;
}
}
}
/* ------ build the line to display -------- */
if ((line = malloc(200)) != NULL) {
if (!trunc) {
if (lnlen < wnd->wleft)
lnlen = 0;
else
lp += wnd->wleft;
if (lnlen > RectLeft(rc)) {
/* ---- the line exceeds the rectangle ---- */
int ct = RectLeft(rc);
char *initlp = lp;
/* --- point to end of clipped line --- */
while (ct) {
if (*(unsigned char *)lp == CHANGECOLOR)
lp += 3;
else if (*(unsigned char *)lp == RESETCOLOR)
lp++;
else
lp++, --ct;
}
if (RectLeft(rc)) {
char *lpp = lp;
while (*lpp) {
if (*(unsigned char*)lpp==CHANGECOLOR)
break;
if (*(unsigned char*)lpp==RESETCOLOR) {
lpp = lp;
while (lpp >= initlp) {
if (*(unsigned char *)lpp ==
CHANGECOLOR) {
lp -= 3;
memmove(lp,lpp,3);
break;
}
--lpp;
}
break;
}
lpp++;
}
}
lnlen = LineLength(lp);
len = min(lnlen, RectWidth(rc));
dif = strlen(lp) - lnlen;
len += dif;
if (len > 0)
strncpy(line, lp, len);
}
}
/* -------- pad the line --------- */
while (len < RectWidth(rc)+dif)
line[len++] = ' ';
line[len] = '\0';
dif = 0;
/* ------ establish the line's main color ----- */
if (reverse) {
char *cp = line;
SetReverseColor(wnd);
while ((cp = strchr(cp, CHANGECOLOR)) != NULL) {
cp += 2;
*cp++ = background | 0x80;
}
if (*(unsigned char *)line == CHANGECOLOR)
dif = 3;
}
else
SetStandardColor(wnd);
/* ------- display the line -------- */
writeline(wnd, line+dif,
RectLeft(rc)+BorderAdj(wnd),
y-wnd->wtop+TopBorderAdj(wnd), FALSE);
free(line);
}
free(svlp);
}
/* ----- set anchor point for marking text block ----- */
void SetAnchor(WINDOW wnd, int mx, int my)
{
if (BlockMarked(wnd)) {
ClearBlock(wnd);
SendMessage(wnd, PAINT, 0, 0);
}
/* ------ set the anchor ------ */
wnd->BlkBegLine = wnd->BlkEndLine = my;
wnd->BlkBegCol = wnd->BlkEndCol = mx;
}
/* ----- clear and initialize text line pointer array ----- */
void ClearTextPointers(WINDOW wnd)
{
wnd->TextPointers = realloc(wnd->TextPointers, sizeof(int));
if (wnd->TextPointers != NULL)
*(wnd->TextPointers) = 0;
}
#define INITLINES 100
/* ---- build array of pointers to text lines ---- */
void BuildTextPointers(WINDOW wnd)
{
char *cp = wnd->text, *cp1;
int incrs = INITLINES;
unsigned int off;
wnd->textwidth = wnd->wlines = 0;
while (*cp) {
if (incrs == INITLINES) {
incrs = 0;
wnd->TextPointers = realloc(wnd->TextPointers,
(wnd->wlines + INITLINES) * sizeof(int));
if (wnd->TextPointers == NULL)
break;
}
off = (unsigned int) (cp - wnd->text);
*((wnd->TextPointers) + wnd->wlines) = off;
wnd->wlines++;
incrs++;
cp1 = cp;
while (*cp && *cp != '\n')
cp++;
wnd->textwidth = max(wnd->textwidth,
(unsigned int) (cp - cp1));
if (*cp)
cp++;
}
}
#ifdef INCLUDE_SCROLLBARS
static void MoveScrollBox(WINDOW wnd, int vscrollbox)
{
foreground = FrameForeground(wnd);
background = FrameBackground(wnd);
PutWindowChar(wnd, WindowWidth(wnd)-1,
wnd->VScrollBox+1, SCROLLBARCHAR);
PutWindowChar(wnd, WindowWidth(wnd)-1,
vscrollbox+1, SCROLLBOXCHAR);
wnd->VScrollBox = vscrollbox;
}
#endif